import logging
import numpy as np
from typing import List, Tuple
from UAS.data.graph_utils import GraphUtils
import os

class GraphValidator:
    def __init__(self, graph_builder):
        """
        初始化GraphValidator
        
        Args:
            graph_builder: GraphBuilder实例，包含图结构和解析器
        """
        self.builder = graph_builder
        self._setup_logging()

    def validate_paths(self) -> List[Tuple[str, str, str]]:
        """
        验证路径有效性并记录详细违规信息
        
        Returns:
            List[Tuple[str, str, str]]: 违规路径列表，每个元素为(起点, 终点, 违规详情)
        """
        dist = self.builder.calculate_floyd()
        violations = []
        total_edges = len(self.builder.G.edges())
        
        for u, v in self.builder.G.edges():
            orig_u = str(self.builder.reverse_mapping[u])
            orig_v = str(self.builder.reverse_mapping[v])
            
            # Validate time matrix entries
            if orig_u not in self.builder.parser.time_matrix:
                logging.warning(f"Missing time matrix entry for node: {orig_u}")
                continue
            if orig_v not in self.builder.parser.time_matrix[orig_u]:
                logging.warning(f"Missing time matrix entry for edge: {orig_u}->{orig_v}")
                continue
                
            direct = self.builder.parser.time_matrix[orig_u][orig_v]
            shortest = dist[u][v]
            #print(f"直连时间: {direct:.1f}，最短路径时间: {shortest:.1f}")

            # 添加浮点数精度容差（1e-3秒）
            if direct - shortest > 1e-3:  # 使用更大的容差值
                # 获取完整最短路径
                path_nodes = GraphUtils.reconstruct_path(self.builder.next_node, u, v)
                if not path_nodes:
                    logging.warning(f"无法重建路径：{orig_u}->{orig_v}")
                    continue
                    
                path_points = [str(self.builder.reverse_mapping[node]) for node in path_nodes]
                
                # 计算路径详细步骤和时间
                path_details = []
                total_time = 0.0
                for i in range(len(path_points)-1):
                    start = path_points[i]
                    end = path_points[i+1]
                    
                    # Validate path segment entries
                    if start not in self.builder.parser.time_matrix:
                        logging.warning(f"Missing time matrix entry for path segment start: {start}")
                        continue
                    if end not in self.builder.parser.time_matrix[start]:
                        logging.warning(f"Missing time matrix entry for path segment: {start}->{end}")
                        continue
                    print(f"start: {start}, end: {end}")
                    print(f"self.builder.parser.time_matrix[start][end]: {self.builder.parser.time_matrix[start][end]}")

                    segment_time = self.builder.parser.time_matrix[start][end]
                    total_time += segment_time
                    path_details.append(f"{start}→{end}({segment_time:.1f})")
                
                violation_details = (
                    f"路径违规: {orig_u}->{orig_v}\n"
                    f"原始直连时间: {direct:.1f} > 最短路径时间: {total_time:.1f}\n"
                    f"最短路径: {' → '.join(map(str, path_points))}\n"
                    f"分段耗时: {' + '.join(map(str, path_details))}"
                )
                
                violations.append((orig_u, orig_v, violation_details))
                
                # 记录详细日志
                logging.warning(
                    f"路径违规: {orig_u}->{orig_v}\n"
                    f"原始直连时间: {direct:.1f} > 最短路径时间: {total_time:.1f}\n"
                    f"最短路径: {' → '.join(path_points)}\n"
                    f"分段耗时: {' + '.join(path_details)}"
                )
        
        logging.info(f"验证完成，共检查{total_edges}条边，发现{len(violations)}条违规路径")
        return violations

    def _setup_logging(self):
        """配置日志记录"""
        try:
            # Ensure output directory exists
            os.makedirs('output', exist_ok=True)
            
            # Configure logging with file handler
            logger = logging.getLogger()
            logger.setLevel(logging.WARNING)
            
            # Remove existing handlers
            for handler in logger.handlers[:]:
                logger.removeHandler(handler)
                
            # Create file handler with explicit encoding and error handling
            # file_handler = logging.FileHandler(
            #     'output/violations.log',
            #     mode='w',  # Overwrite existing file
            #     encoding='utf-8'
            # )
            # file_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
            # logger.addHandler(file_handler)
            
            # Test logging
            # logger.warning("Logging initialized successfully")
        except Exception as e:
            print(f"Error setting up logging: {str(e)}")
